#include <xy/ais/context.h>

namespace xy
{

namespace ais
{

using namespace xy::geom;

context::context(std::shared_ptr<camera> camera) : m_camera(camera), m_mouseMsg(std::make_shared<msg_mouse>())
{
}

void context::mouse_wheel_event(float angleDelta)
{
    if (m_action == Action3d::None)
    {
        m_action = Action3d::Scale;

        auto distance = std::max(1.0f, m_camera->distance() - angleDelta * m_scaleRate);
        m_camera->set_distance(distance);

        m_action = Action3d::None;
    }
}

void context::mouse_press_event(const vec2f &pos, msg_mouse::Button button)
{
    m_mouseMsg->depth = 1.0f;
    m_mouseMsg->button = button;
    m_mouseMsg->status = msg_mouse::Status::Press;

    if (button == msg_mouse::Button::Middle)
        m_action = Action3d::Translate;
    else if (button == msg_mouse::Button::Right)
        m_action = Action3d::Rotate;
}

void context::mouse_release_event(const vec2f &pos)
{
    m_action = Action3d::None;
    m_mouseMsg->depth = 1.0f;
    m_mouseMsg->status = msg_mouse::Status::Press;
}

void context::mouse_move_event(const vec2f &pos)
{
    // 记录之前的位置
    auto prevPos = m_mouseMsg->movePos;

    // 更新鼠标消息
    m_mouseMsg->depth = 2.0f;
    m_mouseMsg->movePos = pos;
    m_mouseMsg->status = msg_mouse::Status::Move;

    if (m_action == Action3d::Rotate)
    {
        // 注意要让画面朝 dv 方向移动，相机要朝 -dv 方向移动
        float dyaw = (prevPos.x() - pos.x()) * m_angleRate;
        float dpitch = (prevPos.y() - pos.y()) * m_angleRate;
        m_camera->set_yaw(m_camera->yaw() + dyaw);
        m_camera->set_pitch(m_camera->pitch() + dpitch);
    }
    else if (m_action == Action3d::Translate)
    {
    }
}

void context::key_event(int key)
{
}

} // namespace ais

} // namespace xy